#!/usr/bin/env python
# -*- encoding: utf-8 -*-
import requests, json
import abc
from xpy3lib.LoggableObject import LoggableObject


class AbsRequestCallCppAPI(LoggableObject):
    """

    """
    __metaclass__ = abc.ABCMeta

    CALL_CPP_API = 'http://190.2.245.29/BGM2M1/api/CallCpp'

    mat_no = None
    json_template_object = None
    payload = None

    def __init__(self, p_mat_no=None, p_json_template_object=None):
        """

        :param p_mat_no:卷号
        :param p_json_template_object:发送给call-cpp接口的json模板, 即按照该模板发送post请求.
        """
        super(AbsRequestCallCppAPI, self).__init__()
        self.mat_no = p_mat_no
        self.json_template_object = p_json_template_object

        try:
            self.payload = p_json_template_object
            # NOTE reset mat_no
            self.payload['Tables'][0]['Rows'][0][0] = self.mat_no
        except Exception as e:
            self.payload = {'message': 'load_request_template_err---->>\n%s' % (str(e))}
            self.logger.error(str(e))

    def request(self):
        """

        :return:
        """
        self.logger.info('AbsRequestCallCppAPI.request')

        p_headers = {'Content-Type': 'text/plain',
                     'Host': 'localhost:8030',
                     'Connection': 'keep-alive',
                     'Origin': 'chrome-extension://fdmmgilgnpjigdojojpjoooidkmcomcm',
                     'Accept': '*/*',
                     'Accept-Encoding': 'gzip, deflate, br',
                     'Accept-Language': 'zh-CN,zh;q=0.9',
                     'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36'}
        #
        try:
            mydata = json.dumps(self.payload)

            self._on_before_request(p_payload=mydata, p_headers=p_headers)

            r = requests.post(url=AbsRequestCallCppAPI.CALL_CPP_API, data=mydata, headers=p_headers, timeout=5)
            d = json.loads(r.text)
            try:
                return self._on_parsing(p_payload=mydata, p_response_dict=d)
            except Exception as e:
                if r is None:
                    r = f'get_none_response_from_{AbsRequestCallCppAPI.CALL_CPP_API}'
                return self._on_parse_fail(p_response=r, p_exception=e)
        except Exception as e:
            self.logger.error(str(e))
            return self._on_request_fail(p_exception=e)

    @abc.abstractmethod
    def _on_before_request(self, p_payload=None, p_headers=None):
        pass

    @abc.abstractmethod
    def _on_request_fail(self, p_exception=None):
        """

        :param p_exception:
        :return:
        """
        self.logger.error('AbsRequestCallCppAPI._on_request_fail---->>\n%s' % (str(p_exception)))
        pass

    @abc.abstractmethod
    def _on_parsing(self, p_payload=None, p_response_dict=None):
        """

        :param p_response_dict:
        :return:
        """
        self.logger.info('AbsRequestCallCppAPI._on_parsing')
        pass

    @abc.abstractmethod
    def _on_parse_fail(self, p_response=None, p_exception=None):
        """

        :param p_exception:
        :return:
        """
        self.logger.error('AbsRequestCallCppAPI._on_parse_fail---->>\n%s' % (str(p_exception)))
        pass
